package com.loong.shop.handler;

import com.google.common.collect.Lists;
import com.loong.common.domain.BaseQuery;
import com.loong.common.domain.Pager;
import com.loong.common.enumerate.ResultCode;
import com.loong.common.exception.GlobalException;
import com.loong.common.executor.BatchExecutor;
import com.loong.common.utils.TransformUtils;
import com.loong.shop.business.GoodsCategoryBusiness;
import com.loong.shop.common.backend.param.GoodsBaseQueryParam;
import com.loong.shop.common.backend.param.GoodsCategoryParam;
import com.loong.shop.common.backend.result.GoodsBaseResult;
import com.loong.shop.common.backend.result.GoodsCategoryResult;
import com.loong.shop.common.forehead.result.GoodsCategoryForeheadResult;
import com.loong.shop.model.GoodsCategory;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 处理商品类别业务的handler
 * @Author: 刘群
 * @Date: 2020/10/27 8:56
 */
@Component
public class GoodsCategoryHandler {

    @Resource
    private GoodsCategoryBusiness categoryBusiness;

    @Resource
    private GoodsBaseHandler goodsBaseHandler;

    @Resource
    private BatchExecutor batchExecutor;

    /**
     * 后台新增商品类别
     * @param param 商品类别封装的参数
     */
    public void saveGoodsCategory(GoodsCategoryParam param) {
        param.setCreateTime(new Date());
        categoryBusiness.save(TransformUtils.transform(param, GoodsCategory.class));
    }

    /**
     * 后台更新商品类别
     * @param param 商品类别封装的参数
     */
    public void updateGoodsCategory(GoodsCategoryParam param) {
        param.setLastUpdateTime(new Date());
        categoryBusiness.updateByPrimaryKeySelective(TransformUtils.transform(param, GoodsCategory.class));
    }

    /**
     * 后台批量删除商品类别
     * @param idList 商品类别id集合
     */
    //TODO 这个删除有问题，需要递归删除。同时若子分类在商品中使用到了，也不能删除。则该如何判断删除的条件
    @Transactional
    public void deleteGoodsCategory(List<Long> idList) {
        ArrayList<Long> ids = Lists.newArrayList();
        batchExecutor.batchExecute(idList,id->id.toString(),(item)->{
            //查询该类别是否使用在商品中，若有则不能删除，若没有则可以直接删除
            GoodsBaseQueryParam param = GoodsBaseQueryParam.builder().brandId(item).build();
            List<GoodsBaseResult> baseResultList = goodsBaseHandler.findGoodsBaseByParam(param);
            if (CollectionUtils.isEmpty(baseResultList)){
//                //先删除所有的子分类，再删除父分类
//                categoryBusiness.deleteCategoryNameByParentId(item);
//                categoryBusiness.deleteById(item);
                ids.add(item);
            }else {
                throw new GlobalException("Goods category is used");
            }
        });
        categoryBusiness.deleteByIds(StringUtils.join(ids,","));
    }

    /**
     * 递归删除
     */
    public void recursionDelete(List<Long> idList){
        List<GoodsCategory> all = categoryBusiness.findAll();
        Set<Long> allIds = new HashSet<>();
        idList.forEach(id->{
            GoodsCategory goodsCategory = new GoodsCategory();
            goodsCategory.setId(id);
            getChildrenIds(goodsCategory,all,allIds);
        });
        allIds.addAll(idList);
        String deleteIds = StringUtils.join(allIds, ",");
        categoryBusiness.deleteByIds(deleteIds);

    }

    /**
     * 获取子节点所有id 如果有资源存在 直接抛出不能删除
     * @param root
     * @param goodsCategoryList
     * @param childrenIds
     * @return
     */
    public Set<Long> getChildrenIds(GoodsCategory root, List<GoodsCategory> goodsCategoryList, Set<Long> childrenIds) {
        if(ObjectUtils.isEmpty(goodsCategoryList))return childrenIds;
        goodsCategoryList
                .stream()
                .filter(position -> position.getParentId().equals(root.getId()))
                .map(goodsCategory->{
                    GoodsBaseQueryParam param = GoodsBaseQueryParam.builder().brandId(goodsCategory.getId()).build();
                    List<GoodsBaseResult> baseResultList = goodsBaseHandler.findGoodsBaseByParam(param);
                    if(!CollectionUtils.isEmpty(baseResultList)){
                        new GlobalException(ResultCode.EXISTS_RESOURCE);
                    }
                    childrenIds.add(goodsCategory.getId());
                    getChildrenIds(goodsCategory, goodsCategoryList,childrenIds);
                    return goodsCategory;
                })
                .collect(Collectors.toList());
        return childrenIds;
    }

    /**
     * 后台分页查询商品类别
     *
     * @param query 查询参数
     * @return 分页结果
     */
    public Pager<GoodsCategoryResult> pageQueryGoodsCategory(BaseQuery query) {
        Pager<GoodsCategory> pager = categoryBusiness.pageQuery(query, () -> categoryBusiness.findAll());
        return TransformUtils.transformPage(pager, GoodsCategoryResult.class);
    }


    /**
     * 封装商品分类树：其他商品会使用到这个。外卖商品暂时没使用到这个
     * @param categoryList 商品分类集合
     * @return 商品分类集合
     */
    private List<GoodsCategoryForeheadResult> packagingCategoriesTree(List<GoodsCategory> categoryList) {
        List<GoodsCategoryForeheadResult> allCategories = TransformUtils.transformList(categoryList, GoodsCategoryForeheadResult.class);
        Long num = 0L;
        Map<Long, GoodsCategoryForeheadResult> map = new HashMap<>();
        List<GoodsCategoryForeheadResult> result = new ArrayList<>();
        //遍历所有的商品分类
        for (GoodsCategoryForeheadResult category : allCategories) {
            if (num.equals(category.getParentId())) {
                result.add(category);//直接将父分类存放到集合中
            }
            map.put(category.getId(), category);//将所有分类都存放到map中
        }
        for (GoodsCategoryForeheadResult category : allCategories) {
            if (!(num.equals(category.getParentId()))) {
                //该分类有父分类，则从Map中获取到该父分类
                GoodsCategoryForeheadResult parent = map.get(category.getParentId());
                if (parent.getChildList() == null) {
                    parent.setChildList(new ArrayList<>());
                }
                //将该分类添加到对应的父分类的集合中
                parent.getChildList().add(category);
            }
        }
        return result;
    }

    /**
     * 前台根据店铺id查询商品分类
     * @param shopId 店铺id
     * @return 商品分类集合
     */
    public List<GoodsCategoryForeheadResult> foreheadFindGoodsCategoryByShopId(Long shopId){
        List<GoodsCategory> categoryList = categoryBusiness.findCategoryByShopId(shopId);
        return TransformUtils.transformList(categoryList,GoodsCategoryForeheadResult.class);
    }

    /**
     * 后台根据店铺id查询商品分类
     * @param shopId 店铺id
     * @return 商品分类集合
     */
    public List<GoodsCategoryResult> findGoodsCategoryByShopId(Long shopId){
        List<GoodsCategory> categoryList = categoryBusiness.findCategoryByShopId(shopId);
        return TransformUtils.transformList(categoryList,GoodsCategoryResult.class);
    }

}
